package com.hbnu.tools;

import com.hbnu.entity.User;
import com.hbnu.entity.UserFile;
import com.hbnu.enums.Status;


import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


public class PrintTool {
    public static void print(String s){
        System.out.print(s);
    }
    public static void println(Object s){
        System.out.println(s);
    }
    static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static String getTime(LocalDateTime localDateTime){
        return formatter.format(localDateTime);
    }

    //问好
    public static String printGreeting() {
        // 获取当前时间
        LocalTime currentTime = LocalTime.now();

        // 获取当前小时数
        int hour = currentTime.getHour();

        // 根据不同的时间段打印不同的问候语
        if (hour < 11) {
            return "Good morning, ";
        } else if (hour < 14) {
            return"Good noon, ";
        } else if (hour < 18) {
            return"Good afternoon, ";
        } else {
            return "Good evening, ";
        }
    }

    //登录错误打印
    public static void logonError(int status){
        String desc=null;
        switch (status){
            case Status.NULL_PASS->desc="密码不能为空";
            case Status.NO_EXIST_USER->desc="用户不存在";
            case Status.ERR_PASS->desc="密码错误";
        }
        println(desc);
    }
    //命令行错误打印
    public static void error(String line,int status){
        String desc=null;
        switch (status){
            case Status.NO_CMD->desc="未找到命令";
            case Status.NULL_PASS->desc="密码不能为空";
            case Status.NO_EXIST_USER->desc="用户不存在";
            case Status.ERR_PASS->desc="密码错误";
            case Status.ERR_PATH->desc="路径错误";
            case Status.EXISTS_FOLDER_NAME->desc="文件夹已存在";
            case Status.ERR_CREATE_FOLDER->desc="文件夹创建失败";
            case Status.ERR_UPDATE->desc="修改异常";
            case Status.ERR_MYSQL->desc="数据库异常";
        }
        println("-bash: "+line+": "+desc);
    }

    //ls


    //打印
    public static void printUserList( Map<Integer,User> userMap){
        String[] headers = {"ID","用户名","注册","登录","使用空间","总空间","是否注销"};
        // head的默认宽带
        int[] maxWidths = {2, 6, 4,4,8,6,8};
        List<String[]> data = new ArrayList<>();
        Set<Integer> idSet = userMap.keySet();
        // 遍历数据计算每列最大显示宽度
        for (Integer id:idSet) {
            User user = userMap.get(id);
            String[] s=new String[]{
                    String.valueOf(id),
                    user.getName(),
                    getTime(user.getCreated_time()),
                    getTime(user.getLogon_time()),
                    formatFileSize(user.getSize()),
                    formatFileSize(user.getSpace()),
                    user.isIs_deleted()?"是":"否"
            };
            for (int i = 0; i < s.length; i++) {
                maxWidths[i] = Math.max(maxWidths[i], getStringDisplayWidth(s[i]));
            }
            data.add(s);
        }
        printGeneral(headers,maxWidths,data);

    }
    public static void printUserFileList(List<UserFile> userFileList) {
        String[] headers = {"ID","用户名称","文件名称","类型"};
        // head的默认宽带
        int[] maxWidths = {2,8,8,4};
        List<String[]> data = new ArrayList<>();

        // 遍历数据计算每列最大显示宽度
        for (UserFile userFile:userFileList) {
            String[] s=new String[]{
                    String.valueOf(userFile.getFid()),
                    userFile.getUname(),
                    userFile.getFname(),
                    userFile.is_file()?"文件":"文件夹"
            };
            for (int i = 0; i < s.length; i++) {
                maxWidths[i] = Math.max(maxWidths[i], getStringDisplayWidth(s[i]));
            }
            data.add(s);
        }
        printGeneral(headers,maxWidths,data);
    }
    //长度
    private static int getStringDisplayWidth(String str) {
        int width = 0;
        for (char c : str.toCharArray()) {
            width += getCharDisplayWidth(c);
        }
        return width;
    }
    //中文
    private static int getCharDisplayWidth(char c) {
        // 使用 Character.UnicodeScript 判断是否为 CJK 字符
        if (Character.isIdeographic(c) ||
                Character.UnicodeScript.of(c) == Character.UnicodeScript.HAN) {
            return 2;  // 中文字符宽度为2
        }
        return 1;     // 其他字符宽度为1
    }
    public static void printGeneral(String[] headers,int[] maxWidths, List<String[]> data) {
        // 打印表头分隔线
        printSeparator(maxWidths);
        // 打印表头
        System.out.print("|");
        for (int i = 0; i < headers.length; i++) {
            System.out.print(" " + padRight(headers[i], maxWidths[i]) + " |");
        }
        System.out.println();

        // 打印表头分隔线
        printSeparator(maxWidths);

        // 打印数据
        for (String[] row : data) {
            System.out.print("|");
            for (int i = 0; i < headers.length; i++) {
                String value = i < row.length ? row[i] : "";
                value = value == null ? "" : value;
                System.out.print(" " + padRight(value, maxWidths[i]) + " |");
            }
            System.out.println();
        }

        // 打印底部分隔线
        printSeparator(maxWidths);
    }
    private static void printSeparator(int[] widths) {
        System.out.print("+");
        for (int width : widths) {
            System.out.print("-".repeat(width + 2) + "+");
        }
        System.out.println();
    }
    private static String padRight(String s, int width) {
        if (s == null) {
            return " ".repeat(width);
        }

        // 计算需要补充的空格数
        int actualWidth = getStringDisplayWidth(s);
        int padSize = width - actualWidth;

        return s + " ".repeat(padSize);
    }






    //打印树结构
    private static final String PIPE = "│   ";
    private static final String MIDDLE_ITEM = "├── ";
    private static final String LAST_ITEM = "└── ";
    private static final String EMPTY_SPACE = "    ";


    private static Map<Integer, UserFile> idUserFileMap;
    public static void printDeleteTree(UserFile userFile,Map<Integer, UserFile> map) {
        //文件映射表
        idUserFileMap=map;
        //root
        println(userFile.getFname() +"/");
        //DFS遍历
        printUserFileTree(userFile, "");
    }

    private static void printUserFileTree(UserFile userFile, String prefix) {
        //进来的一定有子内容
        UserFile[] userFiles =getUserFiles(userFile);

        for (int i = 0; i < userFiles.length; i++) {
            UserFile file = userFiles[i];
            boolean isLast = (i == userFiles.length - 1);//最后一个

            // 打印当前文件或目录
            System.out.print(prefix);
            System.out.print(isLast ? LAST_ITEM : MIDDLE_ITEM);
            System.out.println(file.getFname() +"("+file.getFid()+")"+ (file.is_file() ? "" : "/"));

            // 递归打印子其内容
            if (file.hasChildren()) {
                String newPrefix = prefix + (isLast ? EMPTY_SPACE : PIPE);
                printUserFileTree(file, newPrefix);
            }
        }
    }
    //获得子文件
    private static UserFile[] getUserFiles(UserFile userFile){
        List<Integer> list = userFile.getList();
        UserFile[] userFiles =new UserFile[list.size()];
        int i=0;
        for (Integer integer : list) {
            userFiles[i++]= idUserFileMap.get(integer);
        }
        // 排序：目录在前，文件在后，同类型按字母顺序排序
        Arrays.sort(userFiles, (f1, f2) -> {
            if (!f1.is_file() && f2.is_file()) {
                return -1;
            } else if (f1.is_file() && !f2.is_file()) {
                return 1;
            } else {
                return f1.getFname().compareToIgnoreCase(f2.getFname());
            }
        });
        return userFiles;
    }




    //文件大小显示
    public static String formatFileSize(long size) {
        final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
        int unitIndex = 0;
        double remainingSize = size;

        while (remainingSize >= 1024 && unitIndex < units.length - 1) {
            remainingSize /= 1024;
            unitIndex++;
        }

        return String.format("%.2f %s", remainingSize, units[unitIndex]);
    }
}
